package com.gitee.wsl.service

import com.gitee.wsl.service.task.JobTask
import com.gitee.wsl.service.task.listener.AbstractTaskListener
import com.gitee.wsl.service.task.scope.ResourceTaskScope
import com.gitee.wsl.service.task.SampleTask
import com.gitee.wsl.service.task.Task
import com.gitee.wsl.service.task.listener.TaskListener
import com.gitee.wsl.service.task.scope.TaskScope
import com.gitee.wsl.service.task.TaskStatus
import com.gitee.wsl.service.task.scope.JobTaskScope
import kotlinx.coroutines.Job

interface TaskServer<SCOPE: TaskScope>: Server, TaskListener<SCOPE> {
    fun deleteAll()
}

enum class SeverStatus{
    UNKNOWN,STOPPED,PAUSING,PAUSED,WAIT,RUNNING,FINISHED,FAILED
}

abstract class SampleTaskService<SCOPE: TaskScope>: AbstractTaskService<SampleTask<SCOPE>, SCOPE, TaskStatus>() {

}

abstract class AbstractTaskService<TASK: Task<SCOPE, STATUS>,SCOPE: TaskScope,STATUS>: AbstractTaskListener<SCOPE>(),
    TaskServer<SCOPE> {

    protected val unCompletionTaskMap= mutableMapOf<String, TASK>()

    init {
        initServer()
    }

    override fun start() {
        unCompletionTaskMap.values.forEach{
            it.start()
        }
    }

    override fun stop() {
        unCompletionTaskMap.values.forEach{
            it.stop()
        }
    }

    override fun deleteAll() {
        unCompletionTaskMap.values.forEach{
            if(it is ResourceTaskScope)
               it.delete()
        }
    }

    fun <T:TASK>  addNewTask(task:T){
        unCompletionTaskMap[task.getTaskTag()]=task
    }

    fun <T:TASK>  removeTask(task:T){
        unCompletionTaskMap.remove(task.getTaskTag())
    }

    fun getTask(tag:String):TASK?{
        return unCompletionTaskMap[tag]
    }

    protected open fun initServer(){

    }

}

class SampleTaskManager(): SampleTaskService<JobTaskScope>() {

    fun cancel(job: Job){
        if(job.isActive)
            job.cancel()
        removeTask(JobTask(job))
    }

    fun idleJob(job : Job, uniqueTaskName:String?=null,cancelRun:()->Unit={}){
        addNewTask(JobTask(job))
    }

    fun addJob(job : Job, uniqueTaskName:String?=null,cancelRun:()->Unit={}){
        addNewTask(JobTask(job))
    }


}